package sapling.service;

import org.apache.commons.collections.map.HashedMap;
import org.apache.http.util.TextUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import sapling.api.model.*;
import sapling.dao.*;
import sapling.form.SeekTreeForm;
import sapling.model.AreaLocation;
import sapling.model.LandMass;
import sapling.model.Tree;
import sapling.model.TreeWell;
import sapling.utils.MathUtil;
import sapling.utils.Msg;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.awt.geom.Point2D;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.*;

/**
 * Created by Administrator on 2017/6/21.
 */
@Service
@Transactional
public class LandMassService {

    @Autowired
    private LandMassDao landMassDao;
    @Autowired
    private TreeWellDao treeWellDao;
    @Autowired
    private TreeDao treeDao;
    @Autowired
    private AreaLocationDao areaLocationDao;
    @Autowired
    private AreaLocationService areaLocationService;
    @Autowired
    private CostService costService;
    @Autowired
    private TreeManyDao treeManyDao;
    @Autowired
    EntityManager entityManager;


    private String site = "http://localhost:8090";

    /**
     * 查询所有已分配树坑地块 已种和未种树的地
     *
     * @return
     */
    public List<ApiAreaModel> listLandMass(int state) {
        List<ApiAreaModel> landMasses = new ArrayList<>();
        List<BigInteger> trees = treeWellDao.landMass(state);
        for (BigInteger value : trees) {
            LandMass land = landMassDao.findOne(value.longValue());
            ApiAreaModel api = new ApiAreaModel();
            api.setBreadth(land.getBreadth());
            api.setSerialNumber(land.getAreaLocation().getSerialNumber() + land.getSerialNumber());
            api.setLandMass_id(land.getLandMass_id());
            landMasses.add(api);
        }
        return landMasses;
    }

    public List<ApiLandMassModel> listisEmptyLandMass(int generate) {
        List<LandMass> emptyLandMass = landMassDao.findByGenerate(generate);
        return parseLandMassList(emptyLandMass);
    }

    public List<ApiLandMassModel> listisEmptyLandMassandarea(int generate, long areaid) {
        List<LandMass> emptyLandMass = landMassDao.findbyGenerateandarea(generate, areaid);
        return parseLandMassList(emptyLandMass);
    }

    public List<ApiLandMassModel> parseLandMassList(List<LandMass> list) {
        List<ApiLandMassModel> res = new ArrayList<>();
        for (LandMass landMass : list) {
            res.add(parseLandMass(landMass));
        }
        return res;
    }

    public ApiLandMassModel parseLandMass(LandMass landMass) {
        ApiLandMassModel model = new ApiLandMassModel();
        model.setTreeWell_occupy(treeWellDao.getCountisUse(1, landMass.getLandMass_id()).intValue());
        model.setTreeWell_quantity(treeWellDao.getCountlandmass(landMass.getLandMass_id()).intValue());
        String maxTreeSpeclandmass = treeDao.getMaxTreeSpeclandmass(landMass.getLandMass_id());
        model.setTreeSpecies(maxTreeSpeclandmass);
        model.setSerialNumber(landMass.getAreaLocation().getSerialNumber() + "-" + landMass.getSerialNumber());
        model.setLandMass_id(landMass.getLandMass_id());
        model.setBreadth(landMass.getBreadth());
        model.setLength(landMass.getLength());
        model.setXcoordinate(landMass.getXcoordinate());
        model.setYcoordinate(landMass.getYcoordinate());
        return model;
    }

    public List<ApiAreaModel> parseList(List<LandMass> list) {
        List<ApiAreaModel> res = new ArrayList<>();
        for (LandMass land : list) {
            res.add(parse(land));
        }
        return res;
    }

    public ApiAreaModel parse(LandMass land) {
        ApiAreaModel api = new ApiAreaModel();
        api.setBreadth(land.getBreadth());
        api.setSerialNumber(land.getAreaLocation().getSerialNumber() + land.getSerialNumber());
        api.setLandMass_id(land.getLandMass_id());
        return api;
    }

    public List<ApiLandMassModel> list(int status) {
        List<ApiLandMassModel> apiLandMassModels = new ArrayList<>();
        List<LandMass> landMasses = landMassDao.nullLandMass();
        for (LandMass value : landMasses) {
            ApiLandMassModel apiLandMassModel = new ApiLandMassModel();
            apiLandMassModel.setLandMass_id(value.getLandMass_id());
            apiLandMassModel.setSerialNumber(value.getAreaLocation().getSerialNumber() + value.getSerialNumber());
            apiLandMassModel.setTreeWell_quantity(value.getTreeWells().size());
            apiLandMassModel.setTreeWell_occupy(treeDao.trees(value.getLandMass_id()).size());
            apiLandMassModels.add(apiLandMassModel);
        }
        return apiLandMassModels;
    }

    /**
     * 根据种植方式生成树坑
     *
     * @param way
     * @param gap
     * @param landMass_id
     * @return
     */
    public List<TreeWell> plantWay(int way, double gap, Long landMass_id) {
        LandMass landMass = landMassDao.findOne(landMass_id);
        if (Objects.nonNull(landMass) && landMass.getTreeWells().size() == 0) {
            if (TreeWell.TYPE_TREEWELL_J == way) {
                this.JWay(landMass.getBreadth(), landMass.getLength(), gap, landMass);
            } else if (TreeWell.TYPE_TREEWELL_P == way) {
                this.PWay(landMass.getBreadth(), landMass.getLength(), gap, landMass);
            }
        }
        return landMass.getTreeWells();
    }

    /**
     * "#"字种植方式
     *
     * @param Xlength
     * @param Ylength
     * @param gap
     * @param landMass
     */
    public void JWay(double Xlength, double Ylength, double gap, LandMass landMass) {
        int row = (int) Math.floor((Ylength) / gap)+1;//多少行
        int line = (int) Math.floor((Xlength) / gap)+1;//一行多少列
        int number = 1;
        for (int i = 1; i <= row; i++) {
            for (int j = 1; j <= line; j++) {
                saveTreeWell(i, j, landMass, gap, number++);
            }
        }
        landMass.setRows(row);
        landMass.setColumns(line);
        landMass.setXgap((int) gap);
        landMass.setYgap(gap);
        landMass.setShape(1);
        landMassDao.saveAndFlush(landMass);
    }

    /**
     * “品”字种植方式
     *
     * @param Xlength
     * @param Ylength
     * @param gap
     * @param landMass
     */
    public void PWay(double Xlength, double Ylength, double gap, LandMass landMass) {
        PWay(Xlength,Ylength,gap,gap,landMass,0,0,true);
    }
    private void savePTreeWell(double xpos,double ypos,int row,int line,int number,LandMass landMass){
        TreeWell treeWell = new TreeWell();
        treeWell.setSerialNumber((number+1) + "");
        treeWell.setRow(row);
        treeWell.setLine(line);
        treeWell.setRowdistance(ypos);//计算y坐标
        treeWell.setLinedistance(xpos);//计算X坐标
        treeWell.setLandMass(landMass);
        landMass.setGenerate(1);
        landMassDao.saveAndFlush(landMass);
        treeWellDao.saveAndFlush(treeWell);
    }

    private void saveTreeWell(int i, int j, LandMass landMass, double gap, int number) {
        TreeWell treeWell = new TreeWell();
        treeWell.setSerialNumber((number+1) + "");
        treeWell.setRow(i);
        treeWell.setLine(j);
        double ypos=(i-1) * gap;
        ypos=landMass.getLength()<ypos?landMass.getLength():ypos;
        double xpos=(j-1)*gap;
        xpos=xpos>landMass.getBreadth()?landMass.getBreadth():xpos;
        treeWell.setRowdistance(ypos);//计算y坐标
        treeWell.setLinedistance(xpos);//计算X坐标
        treeWell.setLandMass(landMass);
        landMass.setGenerate(1);
        landMassDao.saveAndFlush(landMass);
        if(landMass.getShapetype()==1) {
            List<Point2D.Double> polygon = new ArrayList<>();
            Point2D.Double lefttop=new Point2D.Double(landMass.getLefttopx(),landMass.getLefttopy());
            Point2D.Double righttop=new Point2D.Double(landMass.getRighttopx(),landMass.getRighttopy());
            Point2D.Double leftdown=new Point2D.Double(landMass.getLeftdownx(),landMass.getLeftdowny());
            Point2D.Double rightdown=new Point2D.Double(landMass.getRightdownx(),landMass.getRightdowny());
            polygon.add(lefttop);
            polygon.add(righttop);
            polygon.add(rightdown);
            polygon.add(leftdown);
            boolean isuse = MathUtil.checkWithJdkGeneralPath(new Point2D.Double(gap+landMass.getXcoordinate()+treeWell.getLinedistance(), landMass.getYcoordinate()+treeWell.getRowdistance()), polygon);
            treeWell.setIsuse(isuse);
        }
        treeWellDao.saveAndFlush(treeWell);
    }

    public ApiAreaSummary getlandmassSummary(long landmassid) {
        LandMass landMass = landMassDao.findOne(landmassid);
        ApiAreaSummary apiAreaSummary = new ApiAreaSummary();
        List<ApiTreeSummary> apiTreeSummaries = parseTreeSummary(landmassid);
        apiAreaSummary.setTreeSummaryList(apiTreeSummaries);
        apiAreaSummary.setColumn(landMass.getColumns());
        apiAreaSummary.setRow(landMass.getRows());
        apiAreaSummary.setShape(landMass.getShape());
//        apiAreaSummary.setGap(landMass.getGap());
        apiAreaSummary.setXgap(landMass.getXgap());
        apiAreaSummary.setYgap(landMass.getYgap());
        apiAreaSummary.setBreadth(landMass.getBreadth());
        apiAreaSummary.setLength(landMass.getLength());
        return apiAreaSummary;
    }

    public List<ApiTreeSummary> parseTreeSummary(long landMassid) {
        List<ApiTreeSummary> res = new ArrayList<>();
        List<TreeWell> treeWells = treeWellDao.getlandMassTreeWell(landMassid);
        for (TreeWell treeWell : treeWells) {
            ApiTreeSummary apiTreeSummary = new ApiTreeSummary();
            apiTreeSummary.setTreeWell(treeWell);
            Tree one = treeDao.findOne(treeWell.getTree_id());
            apiTreeSummary.setTree(one);
            if(one!=null&&one.getHeight()==-1){
                one.setHeight(0);
            }
            res.add(apiTreeSummary);
        }
        return res;
    }

    public List<ApiLandMassSeek> getTreeSpecies(String condition) {
        List<ApiLandMassSeek> apiAreaModels = new ArrayList<>();
        List<Tree> trees = treeDao.findTreeSpecies(condition);
        for (Tree tree : trees) {
            if (Objects.nonNull(tree.getLandmassid())) {
                LandMass landMass = landMassDao.findOne(tree.getLandmassid());
                if (Objects.nonNull(landMass)) {
                    apiAreaModels.add(this.apiLandMassSeek(landMass, tree, condition));
                }
            }
        }
        return apiAreaModels;
    }

    public List<ApiLandSearch> searchBySpecies(String condition) {
        List<ApiLandSearch> apiLandSearchList = new ArrayList<>();
        List<Tree> trees = treeDao.findTreeSpecies(condition);
        for (Tree tree : trees) {
            if (Objects.nonNull(tree.getLandmassid())) {
                LandMass landMass = landMassDao.findOne(tree.getLandmassid());
                if (landMass == null) continue;
                apiLandSearchList.add(parseApiLandSearch(landMass, tree, condition));
            }
        }
        return apiLandSearchList;
    }

    public List<ApiLandSearch> searchByLand(String condition) {
        List<ApiLandSearch> apiAreaModels = new ArrayList<>();
        if (condition.length() > 0) {
            String str[] = condition.split("-");
            if (Objects.nonNull(str[0]) && str[0].length() > 0) {
                AreaLocation areaLocation = areaLocationDao.findbyname(str[0]);
                if (Objects.nonNull(areaLocation)) {
                    if (Objects.nonNull(str[1]) && str[1].length() > 0) {
                        LandMass landMass = landMassDao.findSerialNumber(areaLocation.getAreaLocation_id(), str[1]);
                        apiAreaModels.add(parseApiLandSearch(landMass, condition));
                    }
                }
            }
        }
        return apiAreaModels;
    }

    public List<ApiLandSearch> searchByArea(String condition) {
        List<ApiLandSearch> apiAreaModels = new ArrayList<>();
        AreaLocation areaLocation = areaLocationDao.findbyname(condition);
        if (Objects.nonNull(areaLocation)) {
            List<LandMass> lnadMassList = landMassDao.findArea(areaLocation.getAreaLocation_id());
            for (LandMass land : lnadMassList) {
                LandMass landMass = landMassDao.findOne(land.getLandMass_id());
                apiAreaModels.add(parseApiLandSearch(landMass, condition));
            }
        }
        return apiAreaModels;
    }

    private ApiLandSearch parseApiLandSearch(LandMass landMass, String condition) {
        ApiLandSearch apiLandSearch = new ApiLandSearch();
        apiLandSearch.setLandMass_id(landMass.getLandMass_id());
        apiLandSearch.setSerialNumber(landMass.getAreaLocation().getSerialNumber() + landMass.getSerialNumber());
        apiLandSearch.setBreadth(landMass.getBreadth());
        apiLandSearch.setLength(landMass.getLength());
        apiLandSearch.setTreespecial("树木:");
        apiLandSearch.setGenerate(landMass.getGenerate());
        apiLandSearch.setNumber(treeDao.findTreeNumber(landMass.getLandMass_id()));
        apiLandSearch.setWellnumber(treeWellDao.getCountlandmass(landMass.getLandMass_id()).intValue());
        apiLandSearch.setDienumber(treeDao.getNumberByLandMass(landMass.getLandMass_id(), 5).intValue());
        apiLandSearch.setHaonumber(treeDao.getNumberByLandMass(landMass.getLandMass_id(), 3).intValue());
        apiLandSearch.setOutnumber(treeDao.getNumberByLandMass(landMass.getLandMass_id(), 2).intValue());
        int treeNumber = treeDao.findTreeNumber(landMass.getLandMass_id());
        if (Objects.nonNull(landMass.getTreeWells()) && landMass.getTreeWells().size() > 0) {
            apiLandSearch.setTreeWell_quantity(MathUtil.getInt(treeNumber, landMass.getTreeWells().size()));
        }
        List<String> lists = new ArrayList<>();
        Set<String> set = new HashSet<>();
        List<Tree> trees = treeDao.findBylandmass(landMass.getLandMass_id());
        for (Tree treevalue : trees) {
            if (Objects.nonNull(treevalue.getTreeSpecies()) && treevalue.getTreeSpecies().length() > 0) {
                set.add(treevalue.getTreeSpecies());
            }
        }

        lists.addAll(set);
        apiLandSearch.setTreesplist(lists);
        return apiLandSearch;
    }

    private ApiLandSearch parseApiLandSearch(LandMass landMass, Tree tree, String condition) {
        ApiLandSearch apiLandSearch = new ApiLandSearch();
        apiLandSearch.setLandMass_id(landMass.getLandMass_id());
        apiLandSearch.setSerialNumber(landMass.getAreaLocation().getSerialNumber() + landMass.getSerialNumber());
        apiLandSearch.setTreespecial(condition + ":");
        apiLandSearch.setBreadth(landMass.getBreadth());
        apiLandSearch.setLength(landMass.getLength());
        apiLandSearch.setWellnumber(treeWellDao.getCountlandmass(landMass.getLandMass_id()).intValue());
        apiLandSearch.setNumber(treeDao.findTreeNumber(condition, tree.getLandmassid()));
        apiLandSearch.setGenerate(landMass.getGenerate());
        apiLandSearch.setDienumber(treeDao.getNumberByLandMass(tree.getTreeSpecies(), landMass.getLandMass_id(), 5).intValue());
        apiLandSearch.setHaonumber(treeDao.getNumberByLandMass(tree.getTreeSpecies(), landMass.getLandMass_id(), 3).intValue());
        apiLandSearch.setOutnumber(treeDao.getNumberByLandMass(tree.getTreeSpecies(), landMass.getLandMass_id(), 2).intValue());
        int treeNumber = treeDao.findTreeNumber(landMass.getLandMass_id());
        if (Objects.nonNull(landMass.getTreeWells()) && landMass.getTreeWells().size() > 0) {
            apiLandSearch.setTreeWell_quantity(MathUtil.getInt(treeNumber, landMass.getTreeWells().size()));
        }

        List<String> lists = new ArrayList<>();
        Set<String> set = new HashSet<>();
        List<Tree> trees = treeDao.findBylandmass(landMass.getLandMass_id());
        for (Tree treevalue : trees) {
            if (Objects.nonNull(treevalue.getTreeSpecies()) && treevalue.getTreeSpecies().length() > 0) {
                set.add(treevalue.getTreeSpecies());
            }
        }
        lists.addAll(set);
        apiLandSearch.setTreesplist(lists);
        return apiLandSearch;
    }

    public List<ApiLandMassSeek> getLandMass(String condition) {
        List<ApiLandMassSeek> apiAreaModels = new ArrayList<>();
        if (condition.length() > 0) {
            String str[] = condition.split("-");
            if (Objects.nonNull(str[0]) && str[0].length() > 0) {
                AreaLocation areaLocation = areaLocationDao.findbyname(str[0]);
                if (Objects.nonNull(areaLocation)) {
                    if (Objects.nonNull(str[1]) && str[1].length() > 0) {
                        LandMass landMass = landMassDao.findSerialNumber(areaLocation.getAreaLocation_id(), str[1]);
                        List<Tree> trees = treeDao.findBylandmass(landMass.getLandMass_id());
                        if (Objects.nonNull(trees) && trees.size() > 0) {
                            Tree tree = trees.get(0);
                            apiAreaModels.add(this.apiLandMassSeek(landMass, tree, condition));
                        }
                    }
                }
            }
        }
        return apiAreaModels;
    }

    public List<ApiLandMassSeek> getAreaLandMass(String condition) {
        List<ApiLandMassSeek> apiAreaModels = new ArrayList<>();
        AreaLocation areaLocation = areaLocationDao.findbyname(condition);
        if (Objects.nonNull(areaLocation)) {
            List<LandMass> lnadMassList = landMassDao.findArea(areaLocation.getAreaLocation_id());
            for (LandMass land : lnadMassList) {
                LandMass landMass = landMassDao.findOne(land.getLandMass_id());
                List<Tree> trees = treeDao.findBylandmass(land.getLandMass_id());
                if (Objects.nonNull(trees) && trees.size() > 0) {
                    Tree tree = trees.get(0);
                    apiAreaModels.add(this.apiLandMassSeek(landMass, tree, condition));
                }
            }
        }
        return apiAreaModels;
    }

    public ApiLandMassSeek apiLandMassSeek(LandMass landMass, Tree tree, String condition) {
        ApiLandMassSeek apiLandMassSeek = new ApiLandMassSeek();
        apiLandMassSeek.setSerialNumber(landMass.getAreaLocation().getSerialNumber() + landMass.getSerialNumber());
        apiLandMassSeek.setLandMass_id(landMass.getLandMass_id());
        apiLandMassSeek.setContent("" + tree.getTreeSpecies() +
                treeDao.findTreeNumber(condition, tree.getLandmassid())
                + ";" + (tree.getClump() ? "丛生" : "非丛生")
                + ";高：" + tree.getHeight()
                + ";胸径：" + tree.getChestBreadth());
        apiLandMassSeek.setTreeSpecies(tree.getTreeSpecies());
        apiLandMassSeek.setNumber(treeDao.findTreeNumber(condition, tree.getLandmassid()));
        apiLandMassSeek.setClump(tree.getClump());
        apiLandMassSeek.setHeight(tree.getHeight());
        apiLandMassSeek.setChestBreadth(tree.getChestBreadth());
        return apiLandMassSeek;
    }

    public List<ApiTreeWell>    treeWell(Long landMass_id, String treeSpecies) {
        double costing = costService.costing();
        BigDecimal b = new BigDecimal(costing);
        costing = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
        List<ApiTreeWell> apiTreeWells = new ArrayList<>();
        if (Objects.nonNull(landMass_id)) {
            LandMass landMass = landMassDao.findOne(landMass_id);
            List<Tree> trees = treeDao.findTreeSpeciesGroup(landMass_id);
            Map<String, String> map = new HashedMap();
            if (Objects.nonNull(treeSpecies) && treeSpecies.length() > 0) {
                map.put("1", treeSpecies);
            } else {
                int index = 1;
                for (Tree tree : trees) {
                    map.put(index + "", tree.getTreeSpecies());
                    index++;
                }
            }
            for (TreeWell value : landMass.getTreeWells()) {
                ApiTreeWell apiTreeWell = new ApiTreeWell();
                apiTreeWell.setLine(value.getLine());
                apiTreeWell.setRow(value.getRow());
                apiTreeWell.setUseState(value.getUseState());
                apiTreeWell.setSerialNumber(value.getSerialNumber());
                apiTreeWell.setSalesState(0);
                apiTreeWell.setTreeWell_id(value.getTreeWell_id());

                if (value.getUseState() == 1 && value.getTree_id() != 0) {
                    Tree tree = treeDao.findOne(value.getTree_id());
                    if (Objects.nonNull(tree)) {
                        apiTreeWell.setTree_id(tree.getTree_id());
                        apiTreeWell.setTreeSpecies(tree.getTreeSpecies());
                        apiTreeWell.setHeight(tree.getHeight());
                        apiTreeWell.setChestBreadth(tree.getChestBreadth());
                        apiTreeWell.setCrownWidth(tree.getCrownWidth());
                        apiTreeWell.setClump(tree.getClump());
                        apiTreeWell.setHealthstate(tree.getHealthstate());
                        apiTreeWell.setLocation(tree.getLocation());
                        apiTreeWell.setResponseState(tree.getResponseState());
                        apiTreeWell.setRemark(tree.getRemark());
                        apiTreeWell.setPrice(tree.getPrice());
                        apiTreeWell.setSales(tree.getSales());
                        apiTreeWell.setState(tree.getSalesState());
                        Iterator<Map.Entry<String, String>> iter = map.entrySet().iterator();
                        while (iter.hasNext()) {
                            Map.Entry<String, String> entry = iter.next();
                            String k = entry.getKey();
                            String v = entry.getValue();
                            if (v.equals(tree.getTreeSpecies())) {
                                apiTreeWell.setSalesState(Integer.parseInt(k));
                            }
                        }
                        String number = value.getLandMass().getAreaLocation().getSerialNumber() + value.getLandMass().getSerialNumber() + "-" + value.getSerialNumber();
                        String str="<div style=\"text-align:left;\">";
                        str += "编号：" + number + "<br>树种：" + tree.getTreeSpecies() + "<br>高度：" + tree.getHeight() + "m<br>胸径：" + tree.getChestBreadth() + "m<br>冠幅：" + tree.getCrownWidth();
                        if (Objects.nonNull(tree.getLocation()) && tree.getLocation().length() > 0) {
                            str += "m<br>产地：" + tree.getLocation();
                        }
                        if (tree.getClump()) {
                            str += "<br>丛生";
                        }
                        if (Objects.nonNull(tree.getRemark()) && tree.getRemark().length() > 0) {
                            str += "<br>备注：" + tree.getRemark();
                        }
                        String addres = "";
                        try {
                            addres = "http://" + InetAddress.getLocalHost().getHostAddress() + ":8090/";
                        } catch (UnknownHostException e) {
                            e.printStackTrace();
                        }
                        if (Objects.nonNull(tree.getImgurl()) && !(tree.getImgurl().isEmpty())) {
                            str += "<br><img src=" + addres + tree.getImgurl() + " style=\"width: 100px;height:100px;\" >";
                        }
                        str+="<div>";
                        apiTreeWell.setTitles(str);
                    }
                }
                apiTreeWells.add(apiTreeWell);
            }
        }
        return apiTreeWells;
    }

    public List<ApiTreeWell> serviceTree(SeekTreeForm form) {
        double costing = costService.costing();
        BigDecimal b = new BigDecimal(costing);
        costing = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
        List<ApiTreeWell> apiTreeWells = new ArrayList<>();
        LandMass landMass = landMassDao.findOne(form.getLandMass_id());
        if (Objects.nonNull(form.getLandMass_id())) {
            List<Tree> treeList = treeDao.findTreeSpeciesGroup(form.getLandMass_id());
            List<Tree> trees = treeManyDao.findAll(this.where(form, form.getLandMass_id()));
            Map<String, String> map = new HashedMap();
            int index = 1;
            for (Tree tree : treeList) {
                map.put(index + "", tree.getTreeSpecies());
                index++;
            }
            for (TreeWell value : landMass.getTreeWells()) {
                ApiTreeWell apiTreeWell = new ApiTreeWell();
                apiTreeWell.setLine(value.getLine());
                apiTreeWell.setRow(value.getRow());
                apiTreeWell.setUseState(value.getUseState());
                apiTreeWell.setSerialNumber(value.getSerialNumber());
                apiTreeWell.setSalesState(0);
                apiTreeWell.setTreeWell_id(value.getTreeWell_id());
                if(landMass.getShapetype()==1){
                    if(value.isIsuse()){
                        apiTreeWell.setIsuse(1);
                    }
                }
                if (value.getUseState() == 1 && value.getTree_id() != 0) {
                    Tree tree =null;
                    for (Tree t:trees) {
                        if(t.getTree_well_id()==value.getTreeWell_id()){
                         tree=t;
                        }
                    }
                    if (Objects.nonNull(tree)) {
                        apiTreeWell.setTree_id(tree.getTree_id());
                        apiTreeWell.setTreeSpecies(tree.getTreeSpecies());
                        apiTreeWell.setHeight(tree.getHeight());
                        apiTreeWell.setChestBreadth(tree.getChestBreadth());
                        apiTreeWell.setCrownWidth(tree.getCrownWidth());
                        apiTreeWell.setClump(tree.getClump());
                        apiTreeWell.setHealthstate(tree.getHealthstate());
                        apiTreeWell.setLocation(tree.getLocation());
                        apiTreeWell.setResponseState(tree.getResponseState());
                        apiTreeWell.setRemark(tree.getRemark());
                        apiTreeWell.setPrice(tree.getPrice());
                        apiTreeWell.setSales(tree.getSales());
                        apiTreeWell.setState(tree.getSalesState());
                        Iterator<Map.Entry<String, String>> iter = map.entrySet().iterator();
                        while (iter.hasNext()) {
                            Map.Entry<String, String> entry = iter.next();
                            String k = entry.getKey();
                            String v = entry.getValue();
                            if (v.equals(tree.getTreeSpecies())) {
                               if(form.getTreeSpecies()==null||form.getTreeSpecies().length()==0){
                                   apiTreeWell.setSalesState(Integer.parseInt(k));
                               }else {
                                   apiTreeWell.setSalesState(1);
                               }
                            }
                        }
                        String number = value.getLandMass().getAreaLocation().getSerialNumber() + value.getLandMass().getSerialNumber() + "-" + value.getSerialNumber();
                        String str = "编号：" + number + "<br>成本：" + costing + "<br>树种：" + tree.getTreeSpecies() + "<br>高度：" + tree.getHeight() + "m<br>胸径：" + tree.getChestBreadth() + "m<br>冠幅：" + tree.getCrownWidth();
                        if (Objects.nonNull(tree.getLocation()) && tree.getLocation().length() > 0) {
                            str += "m<br>产地：" + tree.getLocation();
                        }
                        if (Objects.nonNull(tree.getRemark()) && tree.getRemark().length() > 0) {
                            str += "<br>备注：" + tree.getRemark();
                        }
                        if (tree.getClump()) {
                            str += "<br>丛生<br>";
                        }

                        String addres = "";
                        try {
                            addres = "http://" + InetAddress.getLocalHost().getHostAddress() + ":8090/";
                        } catch (UnknownHostException e) {
                            e.printStackTrace();
                        }

                        if (Objects.nonNull(tree.getImgurl()) && !(tree.getImgurl().isEmpty())) {
                            str += "<br><img src=" + addres + tree.getImgurl() + " style=\"width: 100px;height:100px;\" >";
                            apiTreeWell.setImgurl(addres + tree.getImgurl());
                        }
                        apiTreeWell.setTitles(str);
                    }
                }
                apiTreeWells.add(apiTreeWell);
            }
        }
        return apiTreeWells;
    }

    public List<ApiLandMassModel> landplantinfo(Long landMass_id) {
        List<ApiLandMassModel> apilist = new ArrayList<>();
        if (Objects.nonNull(landMass_id)) {
            LandMass value = landMassDao.findOne(landMass_id);
            ApiLandMassModel api = new ApiLandMassModel();
            api.setLandMass_id(value.getLandMass_id());
            api.setSerialNumber(value.getSerialNumber());
            api.setLength(value.getLength());
            api.setBreadth(value.getBreadth());
            int treeNumber = treeDao.findTreeByNumber(value.getLandMass_id());
            List<String> lists = new ArrayList<>();
            Set<String> set = new HashSet<>();
            List<Tree> trees = treeDao.findBylandmass(value.getLandMass_id());
            for (Tree treevalue : trees) {
                if (Objects.nonNull(treevalue.getTreeSpecies()) && treevalue.getTreeSpecies().length() > 0) {
                    set.add(treevalue.getTreeSpecies());
                }
            }
            api.setTreeWell_quantity(treeNumber);
            api.setTreeWell_occupy(value.getTreeWells().size());
            lists.addAll(set);
            api.setTreesplist(lists);
            apilist.add(api);
        }
        return apilist;
    }

    public List<ApiAreaModel> treeSearch(String treeSpecies, String chestBreadth, String salenumber, String heightmin, String heightmax, int clump, Long landmassid){
        List<ApiAreaModel> areaLocationsnew = new ArrayList<>();
        if ((treeSpecies.length() < 1) && (chestBreadth.length() < 1) && (heightmin.length() < 1) && (heightmax.length() < 1) && (heightmax.length() < 1) && (salenumber.length() < 1)) {
            return areaLocationsnew;
        }else{
            StringBuilder sb=new StringBuilder();
            String sqlland="select * from land_mass where id in (select landmassid from tree where id in (select tree_id from tree_well where tree_id in (select id from tree where ";
            boolean isfirst=false;
            if(treeSpecies.length()>0){
                isfirst=true;
                sb.append("tree_species like '"+treeSpecies+"' ");
            }
            if(chestBreadth.length()>0){
                if(isfirst){
                    sb.append(" and ");
                }else{
                    isfirst=true;
                }
                sb.append(" chest_breadth="+chestBreadth);
            }
            if(isfirst){
                sb.append(" and ");
            }else{
                isfirst=true;
            }
            sb.append(" clump="+clump);
            if(salenumber.length()>0){
                if(isfirst){
                    sb.append(" and ");
                }else{
                    isfirst=true;
                }
                sb.append(" salenumber="+salenumber);
            }
            if(heightmin.length()>0){
                if(isfirst){
                    sb.append(" and ");
                }else{
                    isfirst=true;
                }
                sb.append(" height >= "+heightmin);
            }
            if(heightmax.length()>0){
                if(isfirst){
                    sb.append(" and ");
                }else{
                    isfirst=true;
                }
                sb.append(" heightmax <= "+heightmax);
            }
            sqlland+=sb.toString()+" )) group by landmassid)";
            Query nativeQuery = entityManager.createNativeQuery(sqlland, LandMass.class);
            List<LandMass> landMassList = nativeQuery.getResultList();
            String sql="select * from tree where id in (select tree_id from tree_well where tree_id in (select id from tree where "+sb.toString()+" ))";
            Query querytree = entityManager.createNativeQuery(sql, Tree.class);
            List<Tree> resultList = querytree.getResultList();
            Tree tree=null;
            if(resultList.size()>0){
                tree=resultList.get(0);
                if(tree.getHeight()==-1){
                    tree.setHeight(0);
                }
            }
            for(int i=0;i<landMassList.size();i++){
                LandMass landMass=landMassList.get(i);
                ApiAreaModel apiAreaModel=new ApiAreaModel();
                apiAreaModel.setSerialNumber(landMass.getAreaLocation().getSerialNumber()+landMass.getSerialNumber());
                apiAreaModel.setAreaLocation(landMass.getAreaLocation().getSerialNumber()+landMass.getSerialNumber());
                apiAreaModel.setChestBreadth(chestBreadth.length()>0?Double.parseDouble(chestBreadth):tree.getChestBreadth());
                apiAreaModel.setHeight(heightmin.length()>0?Double.parseDouble(heightmin):tree.getHeight());
                apiAreaModel.setHeight(heightmin.length()>0?Double.parseDouble(heightmax):tree.getHeight());
                apiAreaModel.setSalenumber(salenumber.length()>0?Integer.parseInt(salenumber):tree.getSalenumber());
                apiAreaModel.setCrownWidth(tree.getCrownWidth());
                apiAreaModel.setClump(clump==1);
                apiAreaModel.setLandMass_id(landMass.getLandMass_id());
                apiAreaModel.setCrownWidth(0);
                apiAreaModel.setLength(landMass.getLength());
                apiAreaModel.setBreadth(landMass.getBreadth());
                apiAreaModel.setQuantity(landMass.getPlant());
                apiAreaModel.setTreeSpecies(treeSpecies);
                apiAreaModel.setLandMassModels(landplantinfo(landMass.getLandMass_id()));
                areaLocationsnew.add(apiAreaModel);
            }
        }
        return areaLocationsnew;
    }
//    public String searchMax(String field,String where){
//        String sql="select "+field+" from tree where id in (select tree_id from tree_well where tree_id in (select id from tree where "+where+" )) group by "+field;
//        Query nativeQuery = entityManager.createNativeQuery(sql, String.class);
//        try {
//            List<BigDecimal> querylist = nativeQuery.getResultList();
//            if (querylist.size() > 0) {
//                return querylist.get(0).toString();
//            } else {
//                return "0";
//            }
//        }catch (Exception e){
//            return "0";
//        }
//    }
    public List<ApiAreaModel> treeSpecies(String treeSpecies, String chestBreadth, String salenumber, String heightmin, String heightmax, int clump, Long landmassid) {
        List<ApiAreaModel> areaLocations = areaLocationService.treeSpecies(clump);
        List<ApiAreaModel> areaLocationsnew = new ArrayList<>();
        if ((treeSpecies.length() < 1) && (chestBreadth.length() < 1) && (heightmin.length() < 1) && (heightmax.length() < 1) && (heightmax.length() < 1) && (salenumber.length() < 1)) {
            areaLocationsnew = areaLocations;
        } else if ((treeSpecies.length() > 0) && (chestBreadth.length() < 1) && (heightmin.length() < 1) && (heightmax.length() < 1)) {
            for (ApiAreaModel value : areaLocations) {
                if (value.getTreeSpecies().contains(treeSpecies)) {
                    areaLocationsnew.add(value);
                }
            }
        } else if ((treeSpecies.length() > 0) && (chestBreadth.length() > 0) && (salenumber.length() > 0) && (heightmin.length() < 1) && (heightmax.length() < 1)) {
            for (ApiAreaModel value : areaLocations) {
                if ((value.getTreeSpecies().contains(treeSpecies)) && (Double.parseDouble(chestBreadth) == value.getChestBreadth()) && (Integer.parseInt(salenumber) == value.getSalenumber())) {
                    areaLocationsnew.add(value);
                }
            }
        } else if ((heightmin.length() > 0) && (heightmax.length() < 1)) {
            for (ApiAreaModel value : areaLocations) {
                if ((value.getTreeSpecies().contains(treeSpecies)) && (Double.parseDouble(chestBreadth) == value.getChestBreadth()) && (Double.parseDouble(heightmin) <= value.getHeight())) {
                    areaLocationsnew.add(value);
                }
            }
        } else if ((heightmin.length() < 1) && (heightmax.length() > 0)) {
            for (ApiAreaModel value : areaLocations) {
                if ((value.getTreeSpecies().contains(treeSpecies)) && (Double.parseDouble(chestBreadth) == value.getChestBreadth()) && (Double.parseDouble(heightmax) >= value.getHeight())) {
                    areaLocationsnew.add(value);
                }
            }
        } else if ((treeSpecies.length() > 0) && (chestBreadth.length() > 0) && (salenumber.length() > 0) && (heightmin.length() > 0) && (heightmax.length() > 0)) {
            for (ApiAreaModel value : areaLocations) {
                if ((value.getTreeSpecies().contains(treeSpecies))
                        && (Double.parseDouble(chestBreadth) == value.getChestBreadth())
                        && (Double.parseDouble(salenumber) == value.getSalenumber())
                        && ((Double.parseDouble(heightmin) <= value.getHeight()) && (Double.parseDouble(heightmax) >= value.getHeight()))) {
                    areaLocationsnew.add(value);
                }
            }
        } else if ((heightmin.length() > 0) && (heightmax.length() > 0)) {
            for (ApiAreaModel value : areaLocations) {
                if ((Double.parseDouble(heightmin) <= value.getHeight()) && (Double.parseDouble(heightmax) >= value.getHeight())) {
                    areaLocationsnew.add(value);
                }
            }
        } else if ((treeSpecies.length() < 1) && (chestBreadth.length() > 0) && (heightmin.length() > 0) && (heightmax.length() > 0)) {
            for (ApiAreaModel value : areaLocations) {
                if ((value.getTreeSpecies().contains(treeSpecies)) && (Double.parseDouble(chestBreadth) == value.getChestBreadth()) && ((Double.parseDouble(heightmin) <= value.getHeight()) && (Double.parseDouble(heightmax) >= value.getHeight()))) {
                    areaLocationsnew.add(value);
                }
            }
        } else if ((treeSpecies.length() < 1) && (chestBreadth.length() > 0) && (heightmin.length() > 0) && (heightmax.length() > 0)) {
            for (ApiAreaModel value : areaLocations) {
                if ((value.getTreeSpecies().contains(treeSpecies)) && (Double.parseDouble(chestBreadth) == value.getChestBreadth()) && ((Double.parseDouble(heightmin) <= value.getHeight()) && (Double.parseDouble(heightmax) >= value.getHeight()))) {
                    areaLocationsnew.add(value);
                }
            }
        } else if ((treeSpecies.length() > 0) && (chestBreadth.length() < 1) && ((heightmin.length() > 0) && (heightmax.length() > 0))) {
            for (ApiAreaModel value : areaLocations) {
                if ((value.getTreeSpecies().contains(treeSpecies)) && ((Double.parseDouble(heightmin) <= value.getHeight()) && (Double.parseDouble(heightmax) >= value.getHeight()))) {
                    areaLocationsnew.add(value);
                }
            }
        } else if ((treeSpecies.length() < 1) && (chestBreadth.length() > 0) && ((heightmin.length() < 1) && (heightmax.length() < 1))) {
            for (ApiAreaModel value : areaLocations) {
                if ((Double.parseDouble(chestBreadth) == value.getChestBreadth())) {
                    areaLocationsnew.add(value);
                }
            }
        } else if ((treeSpecies.length() < 1) && (chestBreadth.length() < 1) && ((heightmin.length() > 0) && (heightmax.length() > 0))) {
            for (ApiAreaModel value : areaLocations) {
                if ((Double.parseDouble(heightmin) <= value.getHeight()) && (Double.parseDouble(heightmax) >= value.getHeight())) {
                    areaLocationsnew.add(value);
                }
            }
        } else if ((treeSpecies.length() < 1) && (chestBreadth.length() > 0) && ((heightmin.length() > 0) && (heightmax.length() > 0))) {
            for (ApiAreaModel value : areaLocations) {
                if (((Double.parseDouble(heightmin) <= value.getHeight()) && (Double.parseDouble(heightmax) >= value.getHeight())) && (Double.parseDouble(chestBreadth) == value.getChestBreadth())) {
                    areaLocationsnew.add(value);
                }
            }
        } else if ((treeSpecies.length() < 1) && (chestBreadth.length() < 1) && (heightmin.length() > 0) && (heightmax.length() < 1)) {
            for (ApiAreaModel value : areaLocations) {
                if ((Double.parseDouble(heightmin) <= value.getHeight())) {
                    areaLocationsnew.add(value);
                }
            }
        } else if ((treeSpecies.length() < 1) && (chestBreadth.length() < 1) && (heightmin.length() < 1) && (heightmax.length() > 0)) {
            for (ApiAreaModel value : areaLocations) {
                if ((Double.parseDouble(heightmax) >= value.getHeight())) {
                    areaLocationsnew.add(value);
                }
            }
        } else if (salenumber.length() > 0) {
            for (ApiAreaModel value : areaLocations) {
                if ((Integer.parseInt(salenumber) == value.getSalenumber())) {
                    areaLocationsnew.add(value);
                }
            }
        } else if ((treeSpecies.length() > 0) && (chestBreadth.length() > 0) && (heightmin.length() > 0) && (heightmax.length() > 0) && (heightmax.length() > 0) && (salenumber.length() > 0)) {
            for (ApiAreaModel value : areaLocations) {
                if ((value.getTreeSpecies().contains(treeSpecies)) && (Double.parseDouble(chestBreadth) == value.getChestBreadth()) && (Integer.parseInt(salenumber) == value.getSalenumber()) && ((Double.parseDouble(heightmin) <= value.getHeight()) && (Double.parseDouble(heightmax) >= value.getHeight()))) {
                    areaLocationsnew.add(value);
                }
            }
        }
        return areaLocationsnew;
    }

    public LandMass create(Long areaLocation_id, String serialNumber, double length, double breadth, Long Xcoordinate, Long Ycoordinate) {
        AreaLocation areaLocation = areaLocationDao.findOne(areaLocation_id);
        LandMass landMass = new LandMass();
        if (Objects.nonNull(areaLocation)) {
            landMass.setSerialNumber(serialNumber);
            landMass.setShapetype(0);
            landMass.setBreadth(breadth);
            landMass.setLength(length);
            landMass.setXcoordinate(Xcoordinate);
            landMass.setYcoordinate(Ycoordinate);
            landMass.setAreaLocation(areaLocation);
            landMassDao.save(landMass);
        }
        return landMass;
    }

    public Msg<LandMass> update(long areaid, String sername, double length, double breadth, Long Xcoordinate, Long Ycoordinate) {
        if (Objects.nonNull(sername)) {
            LandMass landMass1 = landMassDao.findSerialNumber(areaid, sername);
            AreaLocation areaLocation = landMass1.getAreaLocation();
            if ((Xcoordinate + breadth <= areaLocation.getBreadth()) && (Ycoordinate + length <= areaLocation.getLength())) {
                landMass1.setBreadth(breadth);
                landMass1.setLength(length);
                landMass1.setXcoordinate(Xcoordinate);
                landMass1.setYcoordinate(Ycoordinate);
                landMassDao.saveAndFlush(landMass1);
                return Msg.newMsg(landMass1);
            } else {
                return Msg.fail("参数错误");
            }
        } else {
            return Msg.fail("修改失败");
        }
    }

    public Msg<LandMass> updatecolumn(long areaid, String sername, double length, double breadth, Long Xcoordinate, Long Ycoordinate) {
        if (Objects.nonNull(sername)) {
            LandMass temp = landMassDao.findSerialNumber(areaid, sername);
            List<LandMass> landlist = landMassDao.findcolumn(areaid, temp.getXcoordinate());
            for (LandMass landMass1 : landlist) {
                AreaLocation areaLocation = landMass1.getAreaLocation();
                if ((Xcoordinate + breadth <= areaLocation.getBreadth()) && (Ycoordinate + length <= areaLocation.getLength())) {
                    landMass1.setXcoordinate(Xcoordinate);
                    landMassDao.saveAndFlush(landMass1);
                }
            }
            return update(areaid, sername, length, breadth, Xcoordinate, Ycoordinate);
        } else {
            return Msg.fail("修改失败");
        }
    }

    public String createts(Long areaLocation_id, String serialNumber, String lefttoppoint, String righttoppoint, String leftdownpoint, String rightdownpoint) {
        AreaLocation area = areaLocationDao.findOne(areaLocation_id);
        if(!TextUtils.isEmpty(serialNumber)){
            String[] split = serialNumber.split(";");
            int size=split.length;
            int i=0;
            for(String landname:split){
                LandMass landMass = landMassDao.findSerialNumber(areaLocation_id, serialNumber);
                if(landMass==null) {
                    landMass = new LandMass();
                }
                landMass.setShapetype(1);
                landMass.setSerialNumber(landname);
                float lefttopx=Float.parseFloat(lefttoppoint.split(",")[0]);
                float lefttopy=Float.parseFloat(lefttoppoint.split(",")[1]);
                float righttopx=Float.parseFloat(righttoppoint.split(",")[0]);
                float righttopy=Float.parseFloat(righttoppoint.split(",")[1]);
                float leftdownx=Float.parseFloat(leftdownpoint.split(",")[0]);
                float leftdowny=Float.parseFloat(leftdownpoint.split(",")[1]);
                float rightdownx=Float.parseFloat(rightdownpoint.split(",")[0]);
                float rightdowny=Float.parseFloat(rightdownpoint.split(",")[1]);
                int ltopx = getIndexpoint(size, lefttopx, leftdownx, i);
                landMass.setLefttopx(ltopx);
                int ltopy = getIndexpoint(size, lefttopy, leftdowny, i);
                landMass.setLefttopy(ltopy);
                int ldownx = getIndexpoint(size, lefttopx, leftdownx, i+1);
                landMass.setLeftdownx(ldownx);
                int ldowny = getIndexpoint(size, lefttopy, leftdowny, i+1);
                landMass.setLeftdowny(ldowny);
                int rtopx = getIndexpoint(size, righttopx, rightdownx, i);
                landMass.setRighttopx(rtopx);
                int rtopy = getIndexpoint(size, righttopy, rightdowny, i);
                landMass.setRighttopy(rtopy);
                int rdownx = getIndexpoint(size, righttopx, rightdownx, i+1);
                landMass.setRightdownx(rdownx);
                int rdowny = getIndexpoint(size, righttopy, rightdowny, i+1);
                landMass.setRightdowny(rdowny);
                int minx=ltopx>ldownx?ldownx:ltopx;
                int miny=ltopy>rtopy?rtopy:ltopy;
                float xlen=(rtopx-ltopx)>(rdownx-ldownx)?rtopx-ltopx:rdownx-ldownx;
                float ylen=(ldowny-ltopy)>(rdowny-rtopy)?ldowny-ltopy:rdowny-rtopy;
                landMass.setXcoordinate((long)minx);
                landMass.setYcoordinate((long)miny);
                landMass.setBreadth(xlen);
                landMass.setLength(ylen);
                landMass.setAreaLocation(area);
                landMassDao.saveAndFlush(landMass);
                ++i;
            }
            return "success";
        }
        return "fail";
    }
    private int getIndexpoint(int size,float toppoint,float downpoint,int index){
        return (int)(toppoint+(((downpoint-toppoint)*index)/size));
    }
    public  List<ApiSearch> treeSpecies(SeekTreeForm form) {
        List<LandMass> landMasses = landMassDao.landMassClump(form.getClump());
        List<ApiSearch> apiSearches = new ArrayList<>();
        String treeSpecies=form.getTreeSpecies();
        for (LandMass land : landMasses) {
            List<Tree> trees = treeManyDao.findAll(this.where(form, land.getLandMass_id()));
            if ((Objects.nonNull(trees)) && trees.size() > 0) {
               ApiSearch apiSearch=new ApiSearch();//地块
                apiSearch.setLandMass_id(land.getLandMass_id());
                apiSearch.setSerialNumber(land.getAreaLocation().getSerialNumber() + land.getSerialNumber());
                List<ApiVariety> apiVarieties=new ArrayList<>();//树种
                Set<String> strings=new HashSet<>();
                for (Tree t:trees) {
                    strings.add(t.getTreeSpecies());
                }
                for (String s:strings) {
                    int clock=0;
                    ApiVariety apiVariety =new ApiVariety();
                    apiVariety.setTreeSpecies(s);
                    List<ApiSearchModel> apiSpecs=new ArrayList<>();//规格
                    form.setTreeSpecies(s);
                    List<Tree> treeList = treeManyDao.findAll(this.whereG3(form,land.getLandMass_id()));
                    form.setTreeSpecies(treeSpecies);
                    for (Tree t:treeList) {
                        int number=0;
                        ApiSearchModel apiSearchModel = new ApiSearchModel();
                        apiSearchModel.setLandMass_id(land.getLandMass_id());
                        apiSearchModel.setSerialNumber(land.getAreaLocation().getSerialNumber() + land.getSerialNumber());
                        apiSearchModel.setTreeSpecies(form.getTreeSpecies());
                        form.setHeight(t.getHeight());
                        form.setChestBreadth(t.getChestBreadth());
                        form.setCrownWidth(t.getCrownWidth());
                        List<Tree> treeList1=treeDao.findw6(land.getLandMass_id(),s,(form.getClump()==1?true:false),t.getHeight(),t.getCrownWidth(),t.getChestBreadth());
                        List<Tree> treeList2=new ArrayList<>();
                        for (Tree tree:treeList1) {
                            TreeWell treeWell=treeWellDao.findOne(tree.getTree_well_id());
                            if(tree.getSalesState()==3){
                                number++;
                                clock++;
                            }
                            tree.setPlace(land.getAreaLocation().getSerialNumber()+land.getSerialNumber()+"-"+treeWell.getSerialNumber());
                            treeList2.add(tree);
                        }
                        if(Objects.nonNull(treeList2)&&treeList2.size()>0){
                            apiSearchModel.setQuantity(treeList2.size());
                        }
                        apiSearchModel.setLock(number);
                        apiSearchModel.setHeight(t.getHeight());
                        apiSearchModel.setHeightmax(t.getHeightmax());
                        apiSearchModel.setChestBreadth(t.getChestBreadth());
                        apiSearchModel.setChestBreadthmax(t.getChestBreadthmax());
                        apiSearchModel.setCrownWidth(t.getCrownWidth());
                        apiSearchModel.setCrownWidthmax(t.getCrownWidthmax());
                        apiSearchModel.setSalenumber(t.getSalenumber());
                        apiSearchModel.setCrownWidthmax(t.getSalenumbermax());
                        apiSearchModel.setClump(form.getClump() == 1 ? "丛生" : "非丛生");
                        apiSearchModel.setTrees(treeList2);
                        apiSpecs.add(apiSearchModel);
                    }
                    apiVariety.setLock(clock);
                    apiVariety.setApiSearchModels(apiSpecs);
                    apiVarieties.add(apiVariety);
                }
                apiSearch.setVarietyList(apiVarieties);
                apiSearches.add(apiSearch);
            }
        }
        return apiSearches;
    }

    public Specification<Tree> where(SeekTreeForm form, Long landmassid) {
        return new Specification<Tree>() {
            @Override
            public Predicate toPredicate(Root<Tree> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> predicates = new ArrayList<Predicate>();
                predicates.add(root.get("landmassid").in(landmassid));
                predicates.add(root.get("clump").in(form.getClump()));
                if (null != form.getTreeSpecies() && form.getTreeSpecies().length() > 0) {
                    predicates.add(root.get("treeSpecies").in(form.getTreeSpecies()));
                }

               /* if (Objects.nonNull(form.getHeight_min()) && Objects.nonNull(form.getHeight_max())) {
                    predicates.add(cb.between(root.<Double>get("height"),
                            form.getHeight_min(),
                            form.getHeight_max()));
                }*/
                if (Objects.nonNull(form.getHeight_min()) && Objects.isNull(form.getHeight_max())) {
                    predicates.add(cb.greaterThanOrEqualTo(root.get("height"), form.getHeight_min()));
                }
                if (Objects.isNull(form.getHeight_min()) && Objects.nonNull(form.getHeight_max())) {
                    predicates.add(cb.lessThanOrEqualTo(root.get("heightmax"), form.getHeight_max()));
                }

               /* if (Objects.nonNull(form.getBranch_min()) && Objects.nonNull(form.getBranch_max())) {
                    predicates.add(cb.between(root.<Double>get("salenumber"),
                            form.getBranch_min(),
                            form.getBranch_max()));
                }*/
                if (Objects.nonNull(form.getBranch_min()) && Objects.isNull(form.getBranch_max())) {
                    predicates.add(cb.greaterThanOrEqualTo(root.get("salenumber"), form.getBranch_min()));
                }
                if (Objects.isNull(form.getBranch_min()) && Objects.nonNull(form.getBranch_max())) {
                    predicates.add(cb.lessThanOrEqualTo(root.get("salenumbermax"), form.getBranch_max()));
                }

                /*if (Objects.nonNull(form.getChest_min()) && Objects.nonNull(form.getChest_max())) {
                    predicates.add(cb.between(root.<Double>get("chestBreadth"),
                            form.getChest_min(),
                            form.getChest_max()));
                }*/
                if (Objects.nonNull(form.getChest_min()) && Objects.isNull(form.getChest_max())) {
                    predicates.add(cb.greaterThanOrEqualTo(root.get("chestBreadth"), form.getChest_min()));
                }
                if (Objects.isNull(form.getChest_min()) && Objects.nonNull(form.getChest_max())) {
                    predicates.add(cb.lessThanOrEqualTo(root.get("chestBreadthmax"), form.getChest_max()));
                }


              /*  if (Objects.nonNull(form.getCrown_min()) && Objects.nonNull(form.getCrown_max())) {
                    predicates.add(cb.between(root.<Double>get("crownWidth"),
                            form.getCrown_min(),
                            form.getCrown_max()));
                }*/
                if (Objects.nonNull(form.getCrown_min()) && Objects.isNull(form.getCrown_max())) {
                    predicates.add(cb.greaterThanOrEqualTo(root.get("crownWidth"), form.getCrown_min()));
                }
                if (Objects.isNull(form.getCrown_min()) && Objects.nonNull(form.getCrown_max())) {
                    predicates.add(cb.lessThanOrEqualTo(root.get("crownWidthmax"), form.getCrown_max()));
                }

                return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
            }
        };
    }

    public Specification<Tree> whereGr(SeekTreeForm form, Long landmassid) {
        return new Specification<Tree>() {
            @Override
            public Predicate toPredicate(Root<Tree> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> predicates = new ArrayList<Predicate>();
                predicates.add(root.get("landmassid").in(landmassid));
                predicates.add(root.get("clump").in(form.getClump()));
                if (null != form.getTreeSpecies() && form.getTreeSpecies().length() > 0) {
                    predicates.add(root.get("treeSpecies").in(form.getTreeSpecies()));
                }

               /* if (Objects.nonNull(form.getHeight_min()) && Objects.nonNull(form.getHeight_max())) {
                    predicates.add(cb.between(root.<Double>get("height"),
                            form.getHeight_min(),
                            form.getHeight_max()));
                }*/
                if (Objects.nonNull(form.getHeight_min()) && Objects.isNull(form.getHeight_max())) {
                    predicates.add(cb.greaterThanOrEqualTo(root.get("height"), form.getHeight_min()));
                }
                if (Objects.isNull(form.getHeight_min()) && Objects.nonNull(form.getHeight_max())) {
                    predicates.add(cb.lessThanOrEqualTo(root.get("heightmax"), form.getHeight_max()));
                }
/*
                if (Objects.nonNull(form.getBranch_min()) && Objects.nonNull(form.getBranch_max())) {
                    predicates.add(cb.between(root.<Double>get("salenumber"),
                            form.getBranch_min(),
                            form.getBranch_max()));
                }*/
                if (Objects.nonNull(form.getBranch_min()) && Objects.isNull(form.getBranch_max())) {
                    predicates.add(cb.greaterThanOrEqualTo(root.get("salenumber"), form.getBranch_min()));
                }
                if (Objects.isNull(form.getBranch_min()) && Objects.nonNull(form.getBranch_max())) {
                    predicates.add(cb.lessThanOrEqualTo(root.get("salenumbermax"), form.getBranch_max()));
                }

              /*  if (Objects.nonNull(form.getChest_min()) && Objects.nonNull(form.getChest_max())) {
                    predicates.add(cb.between(root.<Double>get("chestBreadth"),
                            form.getChest_min(),
                            form.getChest_max()));
                }*/
                if (Objects.nonNull(form.getChest_min()) && Objects.isNull(form.getChest_max())) {
                    predicates.add(cb.greaterThanOrEqualTo(root.get("chestBreadth"), form.getChest_min()));
                }
                if (Objects.isNull(form.getChest_min()) && Objects.nonNull(form.getChest_max())) {
                    predicates.add(cb.lessThanOrEqualTo(root.get("chestBreadthmax"), form.getChest_max()));
                }


           /*     if (Objects.nonNull(form.getCrown_min()) && Objects.nonNull(form.getCrown_max())) {
                    predicates.add(cb.between(root.<Double>get("crownWidth"),
                            form.getCrown_min(),
                            form.getCrown_max()));
                }*/
                if (Objects.nonNull(form.getCrown_min()) && Objects.isNull(form.getCrown_max())) {
                    predicates.add(cb.greaterThanOrEqualTo(root.get("crownWidth"), form.getCrown_min()));
                }
                if (Objects.isNull(form.getCrown_min()) && Objects.nonNull(form.getCrown_max())) {
                    predicates.add(cb.lessThanOrEqualTo(root.get("crownWidthmax"), form.getCrown_max()));
                }

                return query.where(predicates.toArray(new Predicate[predicates.size()])).groupBy(root.get("treeSpecies")).getRestriction();
            }
        };
    }

    public Specification<Tree> whereG3(SeekTreeForm form, Long landmassid) {
        return new Specification<Tree>() {
            @Override
            public Predicate toPredicate(Root<Tree> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> predicates = new ArrayList<Predicate>();
                predicates.add(root.get("landmassid").in(landmassid));
                predicates.add(root.get("clump").in(form.getClump()));
                if (null != form.getTreeSpecies() && form.getTreeSpecies().length() > 0) {
                    predicates.add(root.get("treeSpecies").in(form.getTreeSpecies()));
                }

               /* if (Objects.nonNull(form.getHeight_min()) && Objects.nonNull(form.getHeight_max())) {
                    predicates.add(cb.between(root.<Double>get("height"),
                            form.getHeight_min(),
                            form.getHeight_max()));
                }*/
                if (Objects.nonNull(form.getHeight_min()) && Objects.isNull(form.getHeight_max())) {
                    predicates.add(cb.greaterThanOrEqualTo(root.get("height"), form.getHeight_min()));
                }
                if (Objects.isNull(form.getHeight_min()) && Objects.nonNull(form.getHeight_max())) {
                    predicates.add(cb.lessThanOrEqualTo(root.get("heightmax"), form.getHeight_max()));
                }

               /* if (Objects.nonNull(form.getBranch_min()) && Objects.nonNull(form.getBranch_max())) {
                    predicates.add(cb.between(root.<Double>get("salenumber"),
                            form.getBranch_min(),
                            form.getBranch_max()));
                }*/
                if (Objects.nonNull(form.getBranch_min()) && Objects.isNull(form.getBranch_max())) {
                    predicates.add(cb.greaterThanOrEqualTo(root.get("salenumber"), form.getBranch_min()));
                }
                if (Objects.isNull(form.getBranch_min()) && Objects.nonNull(form.getBranch_max())) {
                    predicates.add(cb.lessThanOrEqualTo(root.get("salenumbermax"), form.getBranch_max()));
                }

             /*   if (Objects.nonNull(form.getChest_min()) && Objects.nonNull(form.getChest_max())) {
                    predicates.add(cb.between(root.<Double>get("chestBreadth"),
                            form.getChest_min(),
                            form.getChest_max()));
                }*/
                if (Objects.nonNull(form.getChest_min()) && Objects.isNull(form.getChest_max())) {
                    predicates.add(cb.greaterThanOrEqualTo(root.get("chestBreadth"), form.getChest_min()));
                }
                if (Objects.isNull(form.getChest_min()) && Objects.nonNull(form.getChest_max())) {
                    predicates.add(cb.lessThanOrEqualTo(root.get("chestBreadthmax"), form.getChest_max()));
                }


               /* if (Objects.nonNull(form.getCrown_min()) && Objects.nonNull(form.getCrown_max())) {
                    predicates.add(cb.between(root.<Double>get("crownWidth"),
                            form.getCrown_min(),
                            form.getCrown_max()));
                }*/
                if (Objects.nonNull(form.getCrown_min()) && Objects.isNull(form.getCrown_max())) {
                    predicates.add(cb.greaterThanOrEqualTo(root.get("crownWidth"), form.getCrown_min()));
                }
                if (Objects.isNull(form.getCrown_min()) && Objects.nonNull(form.getCrown_max())) {
                    predicates.add(cb.lessThanOrEqualTo(root.get("crownWidthmax"), form.getCrown_max()));
                }
                return query.where(predicates.toArray(new Predicate[predicates.size()]))
                        .groupBy(root.get("height"))
                        .groupBy(root.get("heightmax"))
                        .groupBy(root.get("chestBreadth"))
                        .groupBy(root.get("chestBreadthmax"))
                        .groupBy(root.get("crownWidth"))
                        .groupBy(root.get("crownWidthmax"))
                        .groupBy(root.get("salenumber"))
                        .groupBy(root.get("salenumbermax"))
                        .getRestriction();
            }
        };
    }

    public Specification<Tree> whereG4(SeekTreeForm form, Long landmassid) {
        return new Specification<Tree>() {
            @Override
            public Predicate toPredicate(Root<Tree> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> predicates = new ArrayList<Predicate>();
                predicates.add(root.get("landmassid").in(landmassid));
                predicates.add(root.get("clump").in(form.getClump()));
                if (null != form.getTreeSpecies() && form.getTreeSpecies().length() > 0) {
                    predicates.add(root.get("treeSpecies").in(form.getTreeSpecies()));
                }

                if (Objects.nonNull(form.getHeight())) {
                    predicates.add(root.get("height").in(form.getHeight()));
                }

                if (Objects.nonNull(form.getBranch_min()) && Objects.nonNull(form.getBranch_max())) {
                    predicates.add(cb.between(root.<Double>get("salenumber"),
                            form.getBranch_min(),
                            form.getBranch_max()));
                }
                if (Objects.nonNull(form.getBranch_min()) && Objects.isNull(form.getBranch_max())) {
                    predicates.add(cb.greaterThanOrEqualTo(root.get("salenumber"), form.getBranch_min()));
                }
                if (Objects.isNull(form.getBranch_min()) && Objects.nonNull(form.getBranch_max())) {
                    predicates.add(cb.lessThanOrEqualTo(root.get("salenumber"), form.getBranch_max()));
                }

                if (Objects.nonNull(form.getChestBreadth())) {
                    predicates.add(root.get("chestBreadth").in(form.getChestBreadth()));
                }


                if (Objects.nonNull(form.getCrownWidth())) {
                    predicates.add(root.get("crownWidth").in(form.getCrownWidth()));
                }

                return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
            }
        };
    }

    public String collect(Long landMass_id) {
        LandMass landMass = landMassDao.findOne(landMass_id);
        String shape = "井";
        if (2 == landMass.getShape()) {
            shape = "品";
        }
        int treewellsum = 0;
        if (Objects.nonNull(landMass.getTreeWells()) && landMass.getTreeWells().size() > 0) {
            treewellsum = landMass.getTreeWells().size();
        }
        List<Tree> treeList = treeDao.findBylandmass(landMass_id);
        int plantsum = 0;
        for (Tree tree : treeList) {
            if (tree.getSalesState() == 0 || tree.getSalesState() == 3 || tree.getSalesState() == 5) {
                plantsum++;
            }
        }
        return "树坑总量：" + treewellsum + "  (" + shape + plantsum + ")";
    }

    public List<TreeWell> plantWay(int way, double xgap,double ygap, Long landMass_id, double x, double y,double xright,double ybottom) {
        LandMass landMass = landMassDao.findOne(landMass_id);
        if (Objects.nonNull(landMass) && landMass.getTreeWells().size() == 0) {
            if (TreeWell.TYPE_TREEWELL_J == way) {
                this.JWay(landMass.getBreadth()-xright, landMass.getLength()-ybottom, xgap,ygap,landMass,x,y);
            } else if (TreeWell.TYPE_TREEWELL_P == way||TreeWell.TYPE_REVTREEWELL_P==way) {
                this.PWay(landMass.getBreadth()-xright, landMass.getLength()-ybottom, xgap,ygap,landMass,x,y,TreeWell.TYPE_TREEWELL_P == way);
            }
        }
        return landMass.getTreeWells();
    }

    private void PWay(double breadth, double length, double xgap,double ygap, LandMass landMass, double x, double y,boolean iszp) {
        int row = (int) Math.floor((length-y) / (ygap/2.0f))+1;//多少行
        int lines=0;
        int number=0;
        for(int i=0;i<row;i++){
            double ypos=i*(ygap/2.0f)+y;
            int temp=i;
            if(!iszp){
                 temp=i+1;
            }
            if(temp%2==0){
                double xpos=x;
                lines=(int)Math.floor((breadth-x)/(xgap*2))+1;
                int line=1;
                while(xpos<=breadth&&line<=lines){
                    savePTreeWell(xpos,ypos,i+1,line,number,landMass);
                    xpos+=xgap*2;
                    ++line;
                    ++number;
                }
            }else{
                double xpos=x+xgap;
                lines=(int)Math.floor((breadth-xpos)/(xgap*2))+1;
                int line=1;
                while(xpos<=breadth&&line<=lines){
                    savePTreeWell(xpos,ypos,i+1,line,number,landMass);
                    xpos+=xgap*2;
                    ++line;
                    ++number;
                }
            }
        }
//        double line = Xlength / gap;//一行多少列
//        int number = 1;
//        for (int i = 1; i <= row; i++) {
//            if (i % 2 == 0) {
//                for (int j = 2; j <= line; j++) {
//                    saveTreeWell(i, j, landMass, gap, number++);
//                }
//            } else {
//                for (int j = 1; j <= line; j++) {
//                    saveTreeWell(i, j, landMass, gap, number++);
//                }
//            }
//        }
        landMass.setRows(row);
        landMass.setXgap(xgap);
        landMass.setYgap(ygap);
        landMass.setColumns(lines);
        landMass.setShape(2);
        landMassDao.saveAndFlush(landMass);
    }

    private void JWay(double breadth, double length, double gap,double ygap,LandMass landMass, double x, double y) {
        int row = (int) Math.floor((length-y) / ygap)+1;//多少行
        int line = (int) Math.floor((breadth-x) / gap)+1;//一行多少列
        int number = 0;
        for (int i = 1; i <= row; i++) {
            for (int j = 1; j <= line; j++) {
                saveTreeWell(i, j, landMass,gap, ygap, number++,x,y);
            }
        }
        landMass.setRows(row);
        landMass.setXgap(gap);
        landMass.setYgap(ygap);
        landMass.setColumns(line);
        landMass.setShape(1);
        landMassDao.saveAndFlush(landMass);
    }
    private void saveTreeWell(int i, int j, LandMass landMass, double gap, double ygap,int number,double x,double y) {
        TreeWell treeWell = new TreeWell();
        treeWell.setSerialNumber((number+1) + "");
        treeWell.setRow(i);
        treeWell.setLine(j);
        double ypos=(i-1) * ygap+y;
        ypos=landMass.getLength()<ypos?landMass.getLength():ypos;
        double xpos=(j-1)*gap+x;
        xpos=xpos>landMass.getBreadth()?landMass.getBreadth():xpos;
        treeWell.setRowdistance(ypos);//计算y坐标
        treeWell.setLinedistance(xpos);//计算X坐标
        treeWell.setLandMass(landMass);
        landMass.setGenerate(1);
        landMassDao.saveAndFlush(landMass);
        treeWellDao.saveAndFlush(treeWell);
    }

}
